﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;

namespace HML
{
    /// <summary>
    /// 滑块
    /// </summary>
    [TypeConverter(typeof(PropertyOrderConverter))]
    public class MultidropSlideThumb
    {
        #region 属性

        private StyleObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleObject(this);
                return this.stateAppearance;
            }
        }

        private string key = "";
        /// <summary>
        /// 滑块Key（必须唯一，可用于索引）
        /// </summary>
        [Description("滑块Key（必须唯一，可用于索引）")]
        [Category("杂项")]
        [PropertyOrder(-198)]
        [DefaultValue("")]
        public string Key
        {
            get { return this.key; }
            set
            {
                if (this.key == value)
                    return;

                this.key = value;
            }
        }

        private string title = "";
        /// <summary>
        /// 滑块标题
        /// </summary>
        [Description("滑块标题")]
        [Category("杂项")]
        [PropertyOrder(-196)]
        [DefaultValue("")]
        public string Title
        {
            get { return this.title; }
            set
            {
                if (this.title == value)
                    return;

                this.title = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private bool lumpLocked = false;
        /// <summary>
        /// 滑块是否已锁定
        /// </summary>
        [Description("滑块是否已锁定")]
        [Category("杂项")]
        [PropertyOrder(-194)]
        [DefaultValue(false)]
        public bool LumpLocked
        {
            get { return this.lumpLocked; }
            set
            {
                if (this.lumpLocked == value)
                    return;

                this.lumpLocked = value;
                if (this.owner != null)
                {
                    this.owner.Invalidate();
                }
            }
        }

        private double selfValue = 0;
        /// <summary>
        /// 滑块值（只修改自己值和触发自己事件，不影响其他滑块值）
        /// </summary>
        [Description("修改滑块值（只修改自己值和触发自己事件，不影响其他滑块值）")]
        [Category("杂项")]
        [PropertyOrder(-192)]
        [DefaultValue(0D)]
        public double SelfValue
        {
            get { return this.selfValue; }
            set
            {
                if (this.selfValue == value)
                    return;

                if (this.owner == null)
                {
                    this.selfValue = value;
                }
                else
                {
                    this.ChangeSelfValue(value, true);
                }
            }
        }

        /// <summary>
        /// 滑块值（修改自己值和触发自己事件，同时影响其他滑块值，直到遇到已锁滑块才终止影响）
        /// </summary>
        [Description("修改滑块值（修改自己值和触发自己事件，同时影响其他滑块值，直到遇到已锁滑块才终止影响）")]
        [Category("杂项")]
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public double InfluencedValue
        {
            get { return this.selfValue; }
            set
            {
                if (this.selfValue == value)
                    return;

                if (this.owner == null)
                {
                    this.selfValue = value;
                }
                else
                {
                    this.ChangeInfluencedValue(value, true);
                }
            }
        }

        private MultidropSlide owner = null;
        /// <summary>
        /// 选项所属的控件
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public MultidropSlide Owner
        {
            get { return this.owner; }
            internal protected set { this.owner = value; }
        }

        #region 临时存储

        /// <summary>
        /// 滑块rect
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal RectangleF LumpRect { get; set; }

        /// <summary>
        /// 滑块开始坐标(滑块中心为参考点)
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal float Lump_Start_Point { get; set; }

        /// <summary>
        /// 滑块结束坐标(滑块中心为参考点)
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal float Lump_End_Point { get; set; }



        /// <summary>
        /// 提示标题rect
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal Rectangle TipTitleRect { get; set; }

        /// <summary>
        /// 提示标题Size
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal Size TipTitleSize { get; set; }

        /// <summary>
        /// 提示标题连线的开始坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipTitleStartPoint { get; set; }

        /// <summary>
        /// 提示标题连线的结束坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipTitleEndPoint { get; set; }



        /// <summary>
        /// 提示值rect
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal Rectangle TipValueRect { get; set; }

        /// <summary>
        /// 提示值Size
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal Size TipValueSize { get; set; }

        /// <summary>
        /// 提示值连线的开始坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipValueStartPoint { get; set; }

        /// <summary>
        /// 提示值连线的结束坐标
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal PointF TipValueEndPoint { get; set; }

        #endregion

        #endregion

        #region 公开方法

        /// <summary>
        /// 修改滑块值，但不会触发任何事情
        /// </summary>
        /// <param name="value"></param>
        internal void OnlySetValue(double value)
        {
            this.selfValue = value;
        }

        /// <summary>
        /// 修改滑块值（只修改自己值和触发自己事件，不影响其他滑块值）
        /// </summary>
        /// <param name="value">要修改的滑块值</param>
        /// <param name="ignoreLocked">是否忽略自己的滑块锁</param>
        /// <returns></returns>
        internal bool ChangeSelfValue(double value, bool ignoreLocked)
        {
            if (this.owner == null || (ignoreLocked == false && this.LumpLocked))
            {
                return false;
            }
            if (this.selfValue == value)
            {
                return false;
            }

            value = Math.Max(value, this.owner.MinValue);
            value = Math.Min(value, this.owner.MaxValue);
            if (this.owner.Items.Count > 1)
            {
                int current_lump_index = this.owner.Items.IndexOf(this);
                // 防止小于左边滑块值
                if (current_lump_index > 0)
                {
                    value = Math.Max(value, this.owner.Items[current_lump_index - 1].SelfValue);
                }
                // 防止大于右边滑块值
                if (current_lump_index < this.owner.Items.Count - 1)
                {
                    value = Math.Min(value, this.owner.Items[current_lump_index + 1].SelfValue);
                }
            }
            if (this.selfValue == value)
            {
                return false;
            }

            this.selfValue = value;
            this.owner.InitializeLumpRectangle(this);
            this.owner.OnValueChanged(new MultidropSlideValueChangedEventArgs(this, this, null));
            this.owner.Invalidate();

            return true;
        }

        /// <summary>
        /// 修改滑块值（修改自己值和触发自己事件，同时影响其他滑块值，直到遇到已锁滑块才终止影响）
        /// </summary>
        /// <param name="value">要修改的滑块值</param>
        /// <param name="ignoreLocked">是否忽略自己的滑块锁</param>
        /// <returns></returns>
        internal bool ChangeInfluencedValue(double value, bool ignoreLocked)
        {
            if (this.owner == null || (ignoreLocked == false && this.LumpLocked))
            {
                return false;
            }

            value = Math.Max(value, this.owner.MinValue);
            value = Math.Min(value, this.owner.MaxValue);
            if (this.selfValue == value)
            {
                return false;
            }

            double selfvalue_tmp = value;
            List<MultidropSlideThumb> influencedLumps = new List<MultidropSlideThumb>();

            if (this.owner.Items.Count > 1)
            {
                int current_lump_index = this.owner.Items.IndexOf(this);

                // 防止小于左边禁止滑块值
                if (value < this.selfValue)
                {
                    for (int i = current_lump_index - 1; i >= 0; i--)
                    {
                        if (this.owner.Items[i].SelfValue > value)
                        {
                            if (this.owner.Items[i].LumpLocked)
                            {
                                selfvalue_tmp = this.owner.Items[i].SelfValue;
                                break;
                            }
                            else
                            {
                                influencedLumps.Add(this.owner.Items[i]);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // 防止大于右边禁止滑块值
                else if (value > this.selfValue)
                {
                    for (int i = current_lump_index + 1; i < this.owner.Items.Count; i++)
                    {
                        if (this.owner.Items[i].SelfValue < value)
                        {
                            if (this.owner.Items[i].LumpLocked)
                            {
                                selfvalue_tmp = this.owner.Items[i].SelfValue;
                                break;
                            }
                            else
                            {
                                influencedLumps.Add(this.owner.Items[i]);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }


                if (this.selfValue == selfvalue_tmp)
                {
                    return false;
                }
                for (int i = influencedLumps.Count - 1; i >= 0; i--)
                {
                    influencedLumps[i].selfValue = selfvalue_tmp;
                    this.owner.InitializeLumpRectangle(influencedLumps[i]);
                    this.owner.OnValueChanged(new MultidropSlideValueChangedEventArgs(this.owner.Items[current_lump_index], influencedLumps[i], influencedLumps));
                }
            }

            this.selfValue = selfvalue_tmp;
            this.owner.InitializeLumpRectangle(this);
            this.owner.OnValueChanged(new MultidropSlideValueChangedEventArgs(this, this, influencedLumps.Count < 1 ? null : influencedLumps));
            this.owner.Invalidate();

            return true;
        }

        /// <summary>
        /// 复制滑块
        /// </summary>
        /// <returns></returns>
        public virtual MultidropSlideThumb Copy()
        {
            MultidropSlideThumb lump = new MultidropSlideThumb() { Key = this.Key, Title = this.Title, SelfValue = this.SelfValue };
            lump.StyleAppearance.Normal.ThumbBorderColor = StyleAppearance.Normal.ThumbBorderColor;
            lump.StyleAppearance.Normal.ThumbBackColor = StyleAppearance.Normal.ThumbBackColor;
            lump.StyleAppearance.Normal.ThumbLockColor = StyleAppearance.Normal.ThumbLockColor;
            lump.StyleAppearance.Normal.TipTitleBorderColor = StyleAppearance.Normal.TipTitleBorderColor;
            lump.StyleAppearance.Normal.TipTitleBackColor = StyleAppearance.Normal.TipTitleBackColor;
            lump.StyleAppearance.Normal.TipTitleTextColor = StyleAppearance.Normal.TipTitleTextColor;
            lump.StyleAppearance.Normal.TipValueBorderColor = StyleAppearance.Normal.TipValueBorderColor;
            lump.StyleAppearance.Normal.TipValueBackColor = StyleAppearance.Normal.TipValueBackColor;
            lump.StyleAppearance.Normal.TipValueTextColor = StyleAppearance.Normal.TipValueTextColor;
            lump.StyleAppearance.Disabled.ThumbBorderColor = StyleAppearance.Disabled.ThumbBorderColor;
            lump.StyleAppearance.Disabled.ThumbBackColor = StyleAppearance.Disabled.ThumbBackColor;
            lump.StyleAppearance.Disabled.ThumbLockColor = StyleAppearance.Disabled.ThumbLockColor;
            lump.StyleAppearance.Disabled.TipTitleBorderColor = StyleAppearance.Disabled.TipTitleBorderColor;
            lump.StyleAppearance.Disabled.TipTitleBackColor = StyleAppearance.Disabled.TipTitleBackColor;
            lump.StyleAppearance.Disabled.TipTitleTextColor = StyleAppearance.Disabled.TipTitleTextColor;
            lump.StyleAppearance.Disabled.TipValueBorderColor = StyleAppearance.Disabled.TipValueBorderColor;
            lump.StyleAppearance.Disabled.TipValueBackColor = StyleAppearance.Disabled.TipValueBackColor;
            lump.StyleAppearance.Disabled.TipValueTextColor = StyleAppearance.Disabled.TipValueTextColor;

            return lump;
        }

        #endregion

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class StyleObject
        {
            private MultidropSlideThumb owner = null;
            internal StyleObject(MultidropSlideThumb owner) { this.owner = owner; }

            #region 属性

            private ItemObject normal;
            /// <summary>
            /// 正常状态
            /// </summary>
            [Description("正常状态")]
            [PropertyOrder(-194)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            public ItemObject Normal
            {
                get
                {
                    if (this.normal == null)
                        this.normal = new ItemObject(this);
                    return this.normal;
                }
            }

            private ItemObject disabled;
            /// <summary>
            /// 禁用状态
            /// </summary>
            [Description("禁用状态")]
            [PropertyOrder(-190)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            public ItemObject Disabled
            {
                get
                {
                    if (this.disabled == null)
                        this.disabled = new ItemObject(this);
                    return this.disabled;
                }
            }

            #endregion

            [TypeConverter(typeof(PropertyOrderConverter))]
            public class ItemObject
            {
                private StyleObject owner = null;
                internal ItemObject(StyleObject owner) { this.owner = owner; }

                #region 私有方法

                /// <summary>
                /// 刷新控件
                /// </summary>
                private void Invalidate()
                {
                    if (this.owner != null && this.owner.owner != null && this.owner.owner.owner != null)
                    {
                        MultidropSlide breadcrumbBar = (MultidropSlide)this.owner.owner.owner;
                        if (breadcrumbBar.Items.Contains(this))
                        {
                            breadcrumbBar.Invalidate();
                        }
                        else
                        {
                            this.owner = null;
                        }
                    }
                }

                #endregion

                #region 属性

                private Color thumbBorderColor = Color.Empty;
                /// <summary>
                /// 拇指边框颜色
                /// </summary>
                [Description("拇指边框颜色")]
                [PropertyOrder(-159)]
                [DefaultValue(typeof(Color), "")]
                public Color ThumbBorderColor
                {
                    get { return this.thumbBorderColor; }
                    set
                    {
                        if (this.thumbBorderColor == value)
                            return;

                        this.thumbBorderColor = value;
                        this.Invalidate();
                    }
                }

                private Color thumbBackColor = Color.Empty;
                /// <summary>
                /// 拇指背景颜色
                /// </summary>
                [Description("拇指背景颜色")]
                [PropertyOrder(-158)]
                [DefaultValue(typeof(Color), "")]
                public Color ThumbBackColor
                {
                    get { return this.thumbBackColor; }
                    set
                    {
                        if (this.thumbBackColor == value)
                            return;

                        this.thumbBackColor = value;
                        this.Invalidate();
                    }
                }

                private Color thumbLockColor = Color.Empty;
                /// <summary>
                /// 拇指锁定颜色
                /// </summary>
                [Description("拇指锁定颜色")]
                [PropertyOrder(-156)]
                [DefaultValue(typeof(Color), "")]
                public Color ThumbLockColor
                {
                    get { return this.thumbLockColor; }
                    set
                    {
                        if (this.thumbLockColor == value)
                            return;

                        this.thumbLockColor = value;
                        this.Invalidate();
                    }
                }

                private Color tipTitleBorderColor = Color.Empty;
                /// <summary>
                /// 标题提示边框颜色
                /// </summary>
                [Description("标题提示边框颜色")]
                [PropertyOrder(-154)]
                [DefaultValue(typeof(Color), "")]
                public Color TipTitleBorderColor
                {
                    get { return this.tipTitleBorderColor; }
                    set
                    {
                        if (this.tipTitleBorderColor == value)
                            return;

                        this.tipTitleBorderColor = value;
                        this.Invalidate();
                    }
                }

                private Color tipTitleBackColor = Color.Empty;
                /// <summary>
                /// 标题提示背景颜色
                /// </summary>
                [Description("标题提示背景颜色")]
                [PropertyOrder(-154)]
                [DefaultValue(typeof(Color), "")]
                public Color TipTitleBackColor
                {
                    get { return this.tipTitleBackColor; }
                    set
                    {
                        if (this.tipTitleBackColor == value)
                            return;

                        this.tipTitleBackColor = value;
                        this.Invalidate();
                    }
                }

                private Color tipTitleTextColor = Color.Empty;
                /// <summary>
                /// 标题提示文本颜色
                /// </summary>
                [Description("标题提示文本颜色")]
                [PropertyOrder(-154)]
                [DefaultValue(typeof(Color), "")]
                public Color TipTitleTextColor
                {
                    get { return this.tipTitleTextColor; }
                    set
                    {
                        if (this.tipTitleTextColor == value)
                            return;

                        this.tipTitleTextColor = value;
                        this.Invalidate();
                    }
                }

                private Color tipValueBorderColor = Color.Empty;
                /// <summary>
                /// 值提示边框颜色
                /// </summary>
                [Description("值提示边框颜色")]
                [PropertyOrder(-154)]
                [DefaultValue(typeof(Color), "")]
                public Color TipValueBorderColor
                {
                    get { return this.tipValueBorderColor; }
                    set
                    {
                        if (this.tipValueBorderColor == value)
                            return;

                        this.tipValueBorderColor = value;
                        this.Invalidate();
                    }
                }

                private Color tipValueBackColor = Color.Empty;
                /// <summary>
                /// 值提示背景颜色
                /// </summary>
                [Description("值提示背景颜色")]
                [PropertyOrder(-154)]
                [DefaultValue(typeof(Color), "")]
                public Color TipValueBackColor
                {
                    get { return this.tipValueBackColor; }
                    set
                    {
                        if (this.tipValueBackColor == value)
                            return;

                        this.tipValueBackColor = value;
                        this.Invalidate();
                    }
                }

                private Color tipValueTextColor = Color.Empty;
                /// <summary>
                /// 值提示文本颜色
                /// </summary>
                [Description("值提示文本颜色")]
                [PropertyOrder(-154)]
                [DefaultValue(typeof(Color), "")]
                public Color TipValueTextColor
                {
                    get { return this.tipValueTextColor; }
                    set
                    {
                        if (this.tipValueTextColor == value)
                            return;

                        this.tipValueTextColor = value;
                        this.Invalidate();
                    }
                }

                #endregion

            }

        }

    }

}
